package com.rock.upms.client.shiro.realm;

import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.rock.common.util.MD5Util;
import com.rock.common.util.SpringContextUtil;
import com.rock.upms.api.model.service.IUpmsDepartmentService;
import com.rock.upms.api.model.service.IUpmsPersonService;
import com.rock.upms.api.model.service.IUpmsSystemService;
import com.rock.upms.api.upms.service.IUpmsService;
import com.rock.upms.client.config.Global;
import com.rock.upms.client.shiro.dto.UsernamePasswordLoginTypeToken;
import com.rock.upms.model.UpmsPerson;
import com.rock.upms.model.UpmsPersonExample;
import com.rock.upms.model.UpmsUser;
import com.rock.upms.model.dto.PermissionDto;
import com.rock.upms.model.dto.RoleDto;
import com.rock.upms.model.dto.UserInfo;

public class UpmsRealm extends AuthorizingRealm {

	private static Logger log = LoggerFactory.getLogger(UpmsRealm.class);
	// @Autowired//通过SpringContextUtil获取实例
	private IUpmsService upmsService;
	private IUpmsPersonService upmsPersonService;
	private IUpmsSystemService upmsSystemService;
	private IUpmsDepartmentService upmsDepartmentService;

	/**
	 * 授权：验证权限时调用
	 * 
	 * @param principalCollection
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		log.trace("--->执行权限验证=====================");
		UserInfo userInfo = (UserInfo) principalCollection.getPrimaryPrincipal();
		// 封装权限验证的数据：角色和权限值=======begin========
		Set<String> roles = new HashSet<>();
		roles.add("login");// 登录成功的均有该角色
		for (RoleDto upmsRole : userInfo.getRoleList()) {
			if (StringUtils.isNotBlank(upmsRole.getRoleCode())) {
				roles.add(upmsRole.getRoleCode());
			}
		}
		Set<String> permissions = new HashSet<>();
		for (PermissionDto permissionDto : userInfo.getPermissionList()) {
			if (StringUtils.isNotBlank(permissionDto.getPermissionValue())) {
				permissions.add(permissionDto.getPermissionValue());
			}
		}
		// 封装权限验证的数据：角色和权限值=======end========
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		simpleAuthorizationInfo.setStringPermissions(permissions);
		simpleAuthorizationInfo.setRoles(roles);
		return simpleAuthorizationInfo;
	}

	/**
	 * 认证：登录时调用
	 * 
	 * @param authToken
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
		UsernamePasswordLoginTypeToken token = (UsernamePasswordLoginTypeToken) authToken;
		String usercode = (String) token.getPrincipal();
		String password = new String((char[]) token.getCredentials());
		String logintype = token.getLoginType();
		// 初始化服务
		upmsService = SpringContextUtil.getBean(IUpmsService.class);
		upmsPersonService = SpringContextUtil.getBean(IUpmsPersonService.class);
		upmsSystemService = SpringContextUtil.getBean(IUpmsSystemService.class);
		upmsDepartmentService = SpringContextUtil.getBean(IUpmsDepartmentService.class);
		// client无密认证
		if ("client".equals(Global.getSSOClientType())) {
			log.trace("--->执行client登录验证=====================");
			UpmsUser defaultUser = upmsService.getDefaultUser(usercode);
			if (defaultUser == null) {
				throw new AuthenticationException("defaultUser为null");
			}
			UserInfo userInfo = upmsService.getUserInfoByUpmsUser(defaultUser);
			// 载入userinfo
			return new SimpleAuthenticationInfo(userInfo, password, getName());
		}
		log.trace("--->sso server登录验证========begin=============");
		// 查询用户信息
		log.trace("--->usercode=====================" + usercode);
		UpmsPersonExample personExample = new UpmsPersonExample();
		personExample.or().andUsercodeEqualTo(usercode);
		UpmsPerson person = upmsPersonService.selectFirstByExample(personExample);
		log.trace("--->person=====================" + person.toString());
		if (person == null) {
			throw new AuthenticationException("person为null");
		} else if (person.getLocked() == 1) {
			throw new LockedAccountException("person 账户被锁定");
		}
		if ("0".equals(logintype)) {
			// 验证密码
			String inputPassword = MD5Util.md5(password + person.getSalt());
			log.trace("--->密码验证begin：" + usercode);
			log.trace("--->密码验证，前台的密码：" + inputPassword);
			log.trace("--->密码验证，数据库密码：" + person.getPassword());
			if (!inputPassword.equals(person.getPassword())) {
				log.trace("--->密码错误");
				log.trace("--->密码验证end：" + usercode);
				throw new IncorrectCredentialsException();
			}
			log.trace("--->密码验证end：密码正确");
		}
		// 密码比对通过初始化登录账户的unserInfo
		UpmsUser defaultUser2 = upmsService.getDefaultUser(usercode);
		UserInfo userInfo2 = upmsService.getUserInfoByUpmsUser(defaultUser2);
		log.trace("--->全局权限数：" + usercode + ":" + userInfo2.getPermissionList().size());
		log.trace("--->全局角色数：" + usercode + ":" + userInfo2.getRoleList().size());
		log.trace("--->sso server登录验证========end=============");
		return new SimpleAuthenticationInfo(userInfo2, password, getName());
	}



	
}
